package oop.ex1.dataStructures;

import java.util.Iterator;

public class LIFOComparableQueue extends AbstractComparableQueue {


	///////////////////////////////////////////////////////
	//////////////////////Constructor//////////////////////
	///////////////////////////////////////////////////////

	/**
	 * Public constructor for a LIFO queue of ComparableObject Type
	 */
	public LIFOComparableQueue() {
		_queue = new ComparableObject[DEFAULT_INITIAL_CAPACITY];
		_size = DEFAULT_STARTING_LOCATION;
	}

	///////////////////////////////////////////////////////
	///////AbstractComparableQueue Implementation//////////
	///////////////////////////////////////////////////////
	
	public void push(ComparableObject obj) {
		_size++;
		if(_size==_queue.length-1) {
			_queue = extendQueue(_queue,_queue.length+DEFAULT_INITIAL_CAPACITY);
		}
		_queue[_size] = obj;
			
	}


	public ComparableObject peek() throws EmptyQueueException {
		if(_size==DEFAULT_STARTING_LOCATION) { 
			throw new EmptyQueueException();
		} else {
			return _queue[_size]; // Return the top-most element
		}
	}



	public ComparableObject poll() throws EmptyQueueException {
		ComparableObject _tmpComparableObject = this.peek(); // An EmptyQueueException will be forwarded throw here
		_queue[_size]=null; // Remove the Element
		_size--;
		return _tmpComparableObject; // Return the top-most element
	}
	
	///////////////////////////////////////////////////////
	///////////////Custom Public methods///////////////////
	///////////////////////////////////////////////////////

	
	/**
	 * Inspects whether the queue is empty or not
	 * @return true if there are no elements in the queue
	 */
	public boolean isQueueEmpty() {
		if(_size==DEFAULT_STARTING_LOCATION) {
			return true;
		} else {
			return false;
		}
	}
	
	///////////////////////////////////////////////////////
	/////////////////////Inner classes/////////////////////
	///////////////////////////////////////////////////////
	

	
	
	@SuppressWarnings("unchecked")
	/**
	 * A class that implements Iterator as a LIFO iterator.
	 */
	private class LIFOIterator implements Iterator {

		//////////////////////Data Members/////////////////////
		
		/**
		 * The current location of the iterator.
		 */
		int _iteratorLocation = _size;
		
		/////////////////////Public methods////////////////////

		/**
		 * 
		 */
		public ComparableObject next() {
			_iteratorLocation--;
			return(_queue[_iteratorLocation+1]);
		}

		/**
		 * 
		 */
		public boolean hasNext() {
			if(_iteratorLocation>DEFAULT_STARTING_LOCATION) {
				return true;
			} else {
				return false;
			}
		}

		
		public void remove() {
			// No Implementation
		}
	}

	@SuppressWarnings("unchecked")
	/**
	 * A method that returns a new LIFOIterator
	 * @return A new LIFOIterator.
	 */
	public Iterator LIFOIterator() {
		return new LIFOIterator();
	}
}
